package cn.zyl.demo.undertow;

import org.xnio.*;
import org.xnio.channels.Channels;
import org.xnio.conduits.ConduitStreamSinkChannel;
import org.xnio.conduits.ConduitStreamSourceChannel;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * XnioSimpleClientServer类说明:
 * <p><a href="https://www.cnblogs.com/jpfss/p/11320744.html">Undertow服务器基础分析 - XNIO</a></p>
 * <p><a href="http://codemacro.com/2017/04/09/xnio-source/">XNIO源码阅读</a></p>
 *
 * @author z.y.l
 * @version v1.0
 * @date 2020-09-07
 */
public class XnioSimpleClientServer {
    public static void main(String[] args) throws IOException {
        final Charset charset = StandardCharsets.UTF_8;
        //创建Xnio实例，并构造XnioWorker
        final Xnio xnio = Xnio.getInstance();
        final XnioWorker worker = xnio.createWorker(OptionMap.EMPTY);

        try {
            //连接服务器，本地12345端口，注意返回值是IoFuture类型，并不阻塞，返回后可以做些别的事情
            final IoFuture<StreamConnection> futureConnection = worker.openStreamConnection(
                    new InetSocketAddress("localhost", 12345), null, OptionMap.EMPTY);
            final StreamConnection channel = futureConnection.get();
            try{
                ConduitStreamSinkChannel sinkChannel = channel.getSinkChannel();
                // 发送消息
                Channels.writeBlocking(sinkChannel, ByteBuffer.wrap("Hello zyl!\n".getBytes(charset)));
                // 保证全部送出
                Channels.flushBlocking(sinkChannel);
                // 发送EOF
                sinkChannel.shutdownWrites();
                System.out.println("Sent greeting string! The response is...");
                ByteBuffer byteBuffer = ByteBuffer.allocate(128);
                ConduitStreamSourceChannel sourceChannel = channel.getSourceChannel();
                // 接收消息
                while (Channels.readBlocking(sourceChannel, byteBuffer) != -1) {
                    byteBuffer.flip();
                    final CharBuffer chars = charset.decode(byteBuffer);
                    System.out.print(chars);
                    byteBuffer.clear();
                }
                sourceChannel.shutdownReads();
            } finally {
                IoUtils.safeClose(channel);
            }
        } finally {
            worker.shutdown();
        }
    }
}
